<?php
namespace Swoole\Thrift;

use Thrift;
use Thrift\Exception\TTransportException;
use Thrift\Transport\TTransport;
use Thrift\Exception\TException;
use Thrift\Factory\TStringFuncFactory;

class HttpStream extends TTransport
{

    const MODE_R = 1;

    const MODE_W = 2;

    private $inStream_ = null;

    private $outStream_ = null;

    private $read_ = false;

    private $write_ = false;

    private $input = null;

    private $output = null;

    public function __construct($mode, $input, $output)
    {
        $this->read_ = $mode & self::MODE_R;
        $this->write_ = $mode & self::MODE_W;
        $this->input = $input;
        $this->output = $output;
    }

    public function open()
    {
        if ($this->read_) {
            $this->inStream_ = $this->input;
        }
        if ($this->write_) {
            $this->outStream_ = $this->output;
        }
    }

    public function close()
    {
        if ($this->read_) {
            $this->inStream_ = null;
        }
        if ($this->write_) {
            $this->outStream_->end('');
        }
    }

    public function isOpen()
    {
        return (! $this->read_ || isset($this->inStream_)) && (! $this->write_ || isset($this->outStream_));
    }

    public function read($len)
    {
        $data = substr($this->inStream_, 0, $len);
        $this->inStream_ = substr($this->inStream_, $len, strlen($this->inStream_) - $len);
        if ($data === FALSE || $data === '') {
            throw new TException('TPhpStream: Could not read ' . $len . ' bytes');
        }
        return $data;
    }

    public function write($buf)
    {
        while (TStringFuncFactory::create()->strlen($buf) > 0) {
            $b = $this->outStream_->write($buf);
            $got = TStringFuncFactory::create()->strlen($buf);
//             $got = @fwrite($this->outStream_, $buf);
            if ($got === false || $got === FALSE) {
                throw new TException('TPhpStream: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes');
            }
            $buf = TStringFuncFactory::create()->substr($buf, $got);
        }
    }

    public function flush()
    {
        //@fflush($this->outStream_);
    }

    private static function inStreamName()
    {
        if (php_sapi_name() == 'cli') {
            return 'php://stdin';
        }
        return 'php://input';
    }
}

?>